Appearance
Java 应用部署到 Docker
从采用最原始的做法手工部署,到集成 Maven 插件半自动部署,最终使用 Jenkins 流水线实现自动化部署。
最原始的做法:手工部署
最原始的做法一般为:
打 JAR 包
sh$ mvn clean package
将 JAR 包上传到服务器(宿主机)
sh$ ls deploy-docker-sample-0.0.1-SNAPSHOT.jar
编写 Dockerfile 文件:
dockerfileFROM eclipse-temurin:17-jdk-alpine COPY deploy-docker-sample-0.0.1-SNAPSHOT.jar /app.jar ENTRYPOINT ["java", "-jar", "/app.jar"] EXPOSE 8080
在服务器上创建 Docker 镜像
sh$ docker build -t localhost:5000/deploy-docker-sample:0.0.1-SNAPSHOT .
基于此镜像启动 Docker 容器
sh$ docker run -d -p 8080:8080 --name deploy-docker-sample localhost:5000/deploy-docker-sample:0.0.1-SNAPSHOT
集成 Maven 插件:半自动部署
使用 dockerfile-maven-plugin
Maven 项目集成
dockerfile-maven-plugin
插件xml<build> <plugins> <plugin> <groupId>com.spotify</groupId> <artifactId>dockerfile-maven-plugin</artifactId> <version>1.4.13</version> <executions> <execution> <id>default</id> <goals> <goal>build</goal> <goal>push</goal> </goals> </execution> </executions> <configuration> <repository>localhost:5000/${project.artifactId}</repository> <tag>${project.version}</tag> <buildArgs> <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE> </buildArgs> </configuration> </plugin> </plugins> </build>
在项目下编写 Dockerfile 文件:
dockerfileFROM eclipse-temurin:17-jdk-alpine ARG JAR_FILE COPY ${JAR_FILE} /app.jar ENTRYPOINT ["java", "-jar", "/app.jar"] EXPOSE 8080
将项目提交到 Git 或 SVN
拉取项目到服务器本地
运行 Maven 打包命令
sh$ mvn clean package ... [INFO] --- dockerfile-maven-plugin:1.4.13:build (default) @ deploy-docker-sample --- [INFO] dockerfile: null [INFO] contextDirectory: /home/ubuntu/maven-projects/deploy-docker-sample [INFO] Building Docker context /home/ubuntu/maven-projects/deploy-docker-sample [INFO] Path(dockerfile): null [INFO] Path(contextDirectory): /home/ubuntu/maven-projects/deploy-docker-sample [INFO] [INFO] Image will be built as localhost:5000/deploy-docker-sample:0.0.1-SNAPSHOT [INFO] [INFO] Step 1/5 : FROM eclipse-temurin:17-jdk-alpine [INFO] [INFO] Pulling from library/eclipse-temurin [INFO] Digest: sha256:85c33b8a96bf36a5335adf754b45575df7df7935a84db560aa8ec16fd40dbf36 [INFO] Status: Image is up to date for eclipse-temurin:17-jdk-alpine [INFO] ---> 9db8c1f3019b [INFO] Step 2/5 : ARG JAR_FILE [INFO] [INFO] ---> Running in e94cb8ed8d94 [INFO] Removing intermediate container e94cb8ed8d94 [INFO] ---> f03aae41fef2 [INFO] Step 3/5 : COPY ${JAR_FILE} /app.jar [INFO] [INFO] ---> 5d31b418687b [INFO] Step 4/5 : ENTRYPOINT ["java", "-jar", "/app.jar"] [INFO] [INFO] ---> Running in e880c7a6c59d [INFO] Removing intermediate container e880c7a6c59d [INFO] ---> c5deb2337484 [INFO] Step 5/5 : EXPOSE 8080 [INFO] [INFO] ---> Running in 1c2e28ada379 [INFO] Removing intermediate container 1c2e28ada379 [INFO] ---> 9235644a9156 [INFO] Successfully built 9235644a9156 [INFO] Successfully tagged localhost:5000/deploy-docker-sample:0.0.1-SNAPSHOT [INFO] [INFO] Detected build of image with id 9235644a9156 [INFO] Building jar: /home/ubuntu/maven-projects/deploy-docker-sample/target/deploy-docker-sample-0.0.1-SNAPSHOT-docker-info.jar [INFO] Successfully built localhost:5000/deploy-docker-sample:0.0.1-SNAPSHOT ...
基于此镜像启动 Docker 容器
sh$ docker run -d -p 8080:8080 --name deploy-docker-sample localhost:5000/deploy-docker-sample:0.0.1-SNAPSHOT
使用 Jenkins 流水线:自动化部署
在集成 Maven 插件:半自动部署的基础上,使用 Jenkins 流水线实现自动化部署。
主要分为两步:自动打包为 Docker 镜像和自动启动 Docker 容器。
自动打包为 Docker 镜像
- 在项目下编写 Jenkinsfile 文件:
jenkinsfile
pipeline {
agent {
docker {
image 'maven:3.8.6-eclipse-temurin-17-alpine'
args '-v $HOME/.m2/:/root/.m2/'
}
}
stages {
stage('Build') {
steps {
sh 'mvn clean package'
}
}
}
}
Jenkins 创建一个流水线项目,指定项目 SCM 地址。具体使用,参见在源代码管理系统中定义流水线。
构建流水线项目。构建成功后便得到了 Docker 镜像。
基于此镜像启动 Docker 容器
sh$ docker run -d -p 8080:8080 --name deploy-docker-sample localhost:5000/deploy-docker-sample:0.0.1-SNAPSHOT
自动启动 Docker 容器
可以看到,上面第 4 步还是需要手动的。所以把这一步也加入流水线便可实现自动化部署。最新的 Jenkinsfile 文件内容如下:
jenkinsfile
pipeline {
agent none
stages {
stage('Build') {
agent {
docker {
image 'maven:3.8.6-eclipse-temurin-17-alpine'
args '-v $HOME/.m2/:/root/.m2/'
}
}
steps {
sh 'mvn clean package'
}
}
stage('Deploy') {
agent any
steps {
sh 'docker run -d -p 8080:8080 --name deploy-docker-sample localhost:5000/deploy-docker-sample:0.0.1-SNAPSHOT'
}
}
}
}